using System;
using System.Data;
using System.Xml;
using System.Runtime.Serialization;
using System.Collections;
using Widgetsphere.Core.Exceptions;
using Widgetsphere.Core.DataAccess;
using ACME.Northwind.Business;
using ACME.Northwind.Business.Objects;
using ACME.Northwind.Business.Rules;
using ACME.Northwind.Business.SelectCommands;
using System.Collections.Generic;

namespace ACME.Northwind.Domain.Objects
{
	/// <summary>
	/// This is an customizable extender for the domain class associated with the 'Order' object
	/// </summary>
	[Serializable()]
	partial class DomainOrder : PersistableDomainObjectBase
	{
		#region Member Variables

		private const string TABLE_NAME = "OrderCollection";
		internal DomainOrderCollection ParentCol;

		#endregion

		#region Constructor

		internal DomainOrder(DataRowBuilder rb) : base(rb) 
		{
			this.ParentCol = ((DomainOrderCollection)(base.Table));
		}

		#endregion

		#region Properties

		internal OrderPrimaryKey PrimaryKey
		{
			get { return new OrderPrimaryKey(this.OrderId); }
		}

		internal string CustomerId
		{
			get
			{
				try
				{
					if (base[this.ParentCol.CustomerIdColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.CustomerIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.CustomerIdColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.CustomerIdColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.CustomerId = value;
				}
			}
		}

		internal int? EmployeeId
		{
			get
			{
				try
				{
					if (base[this.ParentCol.EmployeeIdColumn] == System.DBNull.Value) return null;
					else return ((int?)(base[this.ParentCol.EmployeeIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.EmployeeIdColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.EmployeeIdColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.EmployeeId = value;
				}
			}
		}

		internal decimal? Freight
		{
			get
			{
				try
				{
					if (base[this.ParentCol.FreightColumn] == System.DBNull.Value) return null;
					else return ((decimal?)(base[this.ParentCol.FreightColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.FreightColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.FreightColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.Freight = value;
				}
			}
		}

		internal DateTime? OrderDate
		{
			get
			{
				try
				{
					if (base[this.ParentCol.OrderDateColumn] == System.DBNull.Value) return null;
					else return ((DateTime?)(base[this.ParentCol.OrderDateColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.OrderDateColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.OrderDateColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.OrderDate = value;
				}
			}
		}

		internal int OrderId
		{
			get
			{
				try
				{
					return ((int)(base[this.ParentCol.OrderIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
		}

		internal DateTime? RequiredDate
		{
			get
			{
				try
				{
					if (base[this.ParentCol.RequiredDateColumn] == System.DBNull.Value) return null;
					else return ((DateTime?)(base[this.ParentCol.RequiredDateColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.RequiredDateColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.RequiredDateColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.RequiredDate = value;
				}
			}
		}

		internal string ShipAddress
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipAddressColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipAddressColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipAddressColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipAddressColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipAddress = value;
				}
			}
		}

		internal string ShipCity
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipCityColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipCityColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipCityColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipCityColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipCity = value;
				}
			}
		}

		internal string ShipCountry
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipCountryColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipCountryColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipCountryColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipCountryColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipCountry = value;
				}
			}
		}

		internal string ShipName
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipNameColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipNameColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipNameColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipNameColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipName = value;
				}
			}
		}

		internal DateTime? ShippedDate
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShippedDateColumn] == System.DBNull.Value) return null;
					else return ((DateTime?)(base[this.ParentCol.ShippedDateColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShippedDateColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShippedDateColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShippedDate = value;
				}
			}
		}

		internal string ShipPostalCode
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipPostalCodeColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipPostalCodeColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipPostalCodeColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipPostalCodeColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipPostalCode = value;
				}
			}
		}

		internal string ShipRegion
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipRegionColumn] == System.DBNull.Value) return null;
					else return ((string)(base[this.ParentCol.ShipRegionColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipRegionColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipRegionColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipRegion = value;
				}
			}
		}

		internal int? ShipVia
		{
			get
			{
				try
				{
					if (base[this.ParentCol.ShipViaColumn] == System.DBNull.Value) return null;
					else return ((int?)(base[this.ParentCol.ShipViaColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  object newValue = DomainHelper.PropertySetterHelper(base[this.ParentCol.ShipViaColumn], value, out wasSet);
				if (wasSet) base[this.ParentCol.ShipViaColumn] = newValue;

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderCollection list = (OrderCollection)this.ParentCol.SubDomain[Collections.OrderCollection];
					Order item = list.GetItemByPK(this.OrderId);
					if (item != null) item.ShipVia = value;
				}
			}
		}

		internal virtual BusinessObjectList<OrderDetail> OrderDetailList
		{
			get
			{
				BusinessObjectList<OrderDetail> associatedOrderDetailList = null;
				//if (associatedOrderDetailList == null)
				//{
					associatedOrderDetailList = new BusinessObjectList<OrderDetail>();
					foreach (DomainOrderDetail OrderDetail in base.GetChildRows(ParentCol.OrderOrderDetailRelation))
					{
						if (OrderDetail.RowState != DataRowState.Deleted)
							associatedOrderDetailList.Add(new OrderDetail(OrderDetail));
					}
					associatedOrderDetailList.ObjectAdded += new BusinessObjectEventHandler(AssociatedOrderDetailList_ObjectAdded);
					associatedOrderDetailList.ObjectRemoved += new BusinessObjectEventHandler(AssociatedOrderDetailList_ObjectRemoved);
				//}
				return associatedOrderDetailList;
			}
		}

		internal virtual DomainCustomer CustomerItem
		{
			get { return (DomainCustomer)base.GetParentRow(this.ParentCol.CustomerOrderRelation); }
			set
			{
				if (value != null)
				{
					DomainCustomerCollection list = null;
					if (value.GetType() == typeof(DomainCustomer))
						list = (DomainCustomerCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.CustomerCollection);
					bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
					this.ParentCol.SubDomain.EnforceConstraints = false;
					DomainCustomer customer = (DomainCustomer)value;
					if(customer.ParentCol != list)
					{
						this.ParentCol.SubDomain.Merge(new DataRow[] { customer }, false, MissingSchemaAction.Error);
						customer = list.GetCustomer(customer.CustomerId);
					}
					base.SetParentRow(customer, this.ParentCol.CustomerOrderRelation);
					this.ParentCol.SubDomain.EnsureParentRowsExist();				
					this.ParentCol.SubDomain.EnforceConstraints = oldEc;
				}
				else
				{
					if(this.ParentCol.CustomerIdColumn.AllowDBNull)
					{
						base.SetNull(this.ParentCol.CustomerIdColumn);
					}
					else
					{
						this.Delete();
					}
				}
			}
		}

		internal virtual DomainEmployee EmployeeItem
		{
			get { return (DomainEmployee)base.GetParentRow(this.ParentCol.EmployeeOrderRelation); }
			set
			{
				if (value != null)
				{
					DomainEmployeeCollection list = null;
					if (value.GetType() == typeof(DomainEmployee))
						list = (DomainEmployeeCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.EmployeeCollection);
					bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
					this.ParentCol.SubDomain.EnforceConstraints = false;
					DomainEmployee employee = (DomainEmployee)value;
					if(employee.ParentCol != list)
					{
						this.ParentCol.SubDomain.Merge(new DataRow[] { employee }, false, MissingSchemaAction.Error);
						employee = list.GetEmployee(employee.EmployeeId);
					}
					base.SetParentRow(employee, this.ParentCol.EmployeeOrderRelation);
					this.ParentCol.SubDomain.EnsureParentRowsExist();				
					this.ParentCol.SubDomain.EnforceConstraints = oldEc;
				}
				else
				{
					if(this.ParentCol.EmployeeIdColumn.AllowDBNull)
					{
						base.SetNull(this.ParentCol.EmployeeIdColumn);
					}
					else
					{
						this.Delete();
					}
				}
			}
		}

		internal virtual DomainShipper ShipperItem
		{
			get { return (DomainShipper)base.GetParentRow(this.ParentCol.ShipperOrderRelation); }
			set
			{
				if (value != null)
				{
					DomainShipperCollection list = null;
					if (value.GetType() == typeof(DomainShipper))
						list = (DomainShipperCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.ShipperCollection);
					bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
					this.ParentCol.SubDomain.EnforceConstraints = false;
					DomainShipper shipper = (DomainShipper)value;
					if(shipper.ParentCol != list)
					{
						this.ParentCol.SubDomain.Merge(new DataRow[] { shipper }, false, MissingSchemaAction.Error);
						shipper = list.GetShipper(shipper.ShipperId);
					}
					base.SetParentRow(shipper, this.ParentCol.ShipperOrderRelation);
					this.ParentCol.SubDomain.EnsureParentRowsExist();				
					this.ParentCol.SubDomain.EnforceConstraints = oldEc;
				}
				else
				{
					if(this.ParentCol.ShipViaColumn.AllowDBNull)
					{
						base.SetNull(this.ParentCol.ShipViaColumn);
					}
					else
					{
						this.Delete();
					}
				}
			}
		}

		#endregion

		#region Collection Operation Methods

		/// <summary>
		/// Serves as a hash function for this particular type.
		/// </summary>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj == null) return false;
			if (obj.GetType() != this.GetType()) return false;

			if ((this.RowState == DataRowState.Deleted) ||
				(((DataRow)obj).RowState == DataRowState.Deleted) ||
				(this.RowState == DataRowState.Detached) ||
				(((DataRow)obj).RowState == DataRowState.Detached))
				return false;

			return ((DomainOrder)obj).PrimaryKey.Equals(this.PrimaryKey);
		}

		public override void Persist()
		{
			DomainHelper.PersistDomainObject(this, this.ParentCol.SubDomain, Collections.OrderCollection, this.ParentCol.Modifier);
		}

		public override void Remove()
		{
			this.ParentCol.RemoveOrder(this);
		}

		#endregion

		#region Relationship Methods
		private void AssociatedOrderDetailList_ObjectAdded(object sender, Widgetsphere.Core.EventArgs.BusinessObjectEventArgs e)
		{
			DomainOrderDetail addedItem = (DomainOrderDetail)e.BusinessObject.WrappedClass;
			DomainOrderDetailCollection existingOrderDetailCollection = (DomainOrderDetailCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.OrderDetailCollection);
			bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
			this.ParentCol.SubDomain.EnforceConstraints = false;
			if(addedItem.ParentCol != existingOrderDetailCollection)
			{
				this.ParentCol.SubDomain.Merge(new DataRow[] { addedItem } , false, MissingSchemaAction.Error);
				addedItem = existingOrderDetailCollection.GetOrderDetail(addedItem.OrderId, addedItem.ProductId);
				e.BusinessObject.WrappedClass = addedItem;
			}
			addedItem.SetParentRow(this,this.ParentCol.OrderOrderDetailRelation);
			this.ParentCol.SubDomain.EnforceConstraints = oldEc;
		}

		private void AssociatedOrderDetailList_ObjectRemoved(object sender, Widgetsphere.Core.EventArgs.BusinessObjectEventArgs e)
		{
			DomainOrderDetail removedItem = (DomainOrderDetail)e.BusinessObject.WrappedClass;
			bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
			this.ParentCol.SubDomain.EnforceConstraints = false;
			removedItem.Delete();
			this.ParentCol.SubDomain.EnforceConstraints = oldEc;
		}

		internal virtual void ReleaseNonIdentifyingRelationships()
		{
		}

		#endregion
	}
}
